/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package unc.pds.data;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.util.Date;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import unc.pds.auth.IPDSSecurity;
import unc.pds.auth.SecurityST;
import unc.pds.exc.CannotInitSecurityException;
import unc.pds.exc.NotEnoughRightException;
import unc.pds.exc.PDSSecurityException;
import unc.pds.util.Arch;

/**
 *
 * @author ain
 */
public class RootDataBean implements EntityBean {

    private EntityContext context;
    private Long object_id;
    private Long parent_id;
    private String name;
    private Date date;
    private Long object_type_id;
    private String object_type_name;
    private Long sessionKey;
    private Hashtable fields;
    private Hashtable contents;
    private String author;
    // <editor-fold defaultstate="collapsed" desc="EJB infrastructure methods. Click the + sign on the left to edit the code.">
    // TODO Add code to acquire and use other enterprise resources (DataSource, JMS, enterprise beans, Web services)
    // TODO Add business methods
    // TODO Add create methods
    /**
     * @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)
     */
    public void setEntityContext(EntityContext aContext) {
        context = aContext;
    }

    /**
     * @see javax.ejb.EntityBean#ejbActivate()
     */
    public void ejbActivate() {
    }

    /**
     * @see javax.ejb.EntityBean#ejbPassivate()
     */
    public void ejbPassivate() {
    }

    /**
     * @see javax.ejb.EntityBean#ejbRemove()
     */
    public void ejbRemove() {
    }

    /**
     * @see javax.ejb.EntityBean#unsetEntityContext()
     */
    public void unsetEntityContext() {
        context = null;
    }

    /**
     * @see javax.ejb.EntityBean#ejbLoad()
     */
    public void ejbLoad() {
        // TODO add code to retrieve data
        //if (Consts.DEBUG_MODE) System.out.println("        try load");
        Long aKey = (Long) context.getPrimaryKey();
        fields = new Hashtable();
        contents = new Hashtable();
        friendlist = new Hashtable();
        enemylist = new Hashtable();
        wanfriendlist = new Hashtable();
        DateFormat df = new SimpleDateFormat("DD.MM.yyyy hh:mm:ssa");
        if (aKey != null) {
            try {
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("SELECT "
                            + Consts.OBJECTS__OBJECT_ID + ","
                            + Consts.OBJECTS__PARENT_ID + ","
                            + Consts.OBJECTS__OBJECT_TYPE_ID + ","
                            + Consts.OBJECTS__NAME + ","
                            + "TO_CHAR(ATIME,'DD.MM.YYYY HH:MI:SSam') chartime "
                            + " FROM " + Consts.OBJECTS__TABLENAME
                            + " WHERE OBJECT_ID='" + aKey + "'");
                    if (ans.next()) {
                        object_id = aKey;
                        parent_id = new Long(ans.getLong(Consts.OBJECTS__PARENT_ID));
                        object_type_id = new Long(ans.getLong(Consts.OBJECTS__OBJECT_TYPE_ID));
                        name = ans.getString(Consts.OBJECTS__NAME);
                        date = df.parse(ans.getString("chartime"));
                    } else {
                        throw new EJBException("not such emp");
                    }
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new EJBException("load: " + e.toString());
            }
        }
        //throw new EJBException();
    }

    /**
     * @see javax.ejb.EntityBean#ejbStore()
     */
    public void ejbStore() {
        // TODO add code to persist data
    }

    // </editor-fold>
    /**
     * See EJB 2.0 and EJB 2.1 section 12.2.5
     */
    public java.lang.Long ejbFindByPrimaryKey(java.lang.Long aKey) throws FinderException {
        // TODO add code to locate aKey from persistent storage
        // throw javax.ejb.ObjectNotFoundException if aKey is not in
        // persistent storage.
        if (aKey != null) {
            try {
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("SELECT * FROM OBJECTS WHERE OBJECT_ID='" + aKey + "'");
                    ResultSetMetaData rsmd = ans.getMetaData();
                    if (ans.next()) {
                        //if (Consts.DEBUG_MODE) System.out.println("        founded");
                        return aKey;
                    } else {
                        throw new FinderException("not user for " + aKey);
                    }
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new FinderException(e.toString());
            }
        }
        throw new FinderException("key is null");
    }
    public java.lang.Long ejbFindByPrimaryKey(java.lang.Long aKey, String type) throws FinderException {
        // TODO add code to locate aKey from persistent storage
        // throw javax.ejb.ObjectNotFoundException if aKey is not in
        // persistent storage.
        if (aKey != null) {
            try {
                Long type_id = getObjectTypeID(type);
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("SELECT * FROM OBJECTS "
                            + "WHERE "
                            + "OBJECT_ID=" + aKey + " AND "
                            + "OBJECT_TYPE_ID="+type_id);
                    ResultSetMetaData rsmd = ans.getMetaData();
                    if (ans.next()) {
                        //if (Consts.DEBUG_MODE) System.out.println("        founded");
                        return aKey;
                    } else {
                        throw new FinderException("not user for " + aKey);
                    }
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new FinderException(e.toString());
            }
        }
        throw new FinderException("key is null");
    }

    public java.util.Collection ejbFindByParentKey(java.lang.Long key) throws FinderException {
        if (key != null) {
            try {
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("SELECT * "
                            + " FROM "+Consts.OBJECTS__TABLENAME
                            + " WHERE "+Consts.OBJECTS__PARENT_ID+"=" + key
                            + " ORDER BY "+Consts.OBJECTS__TIME+" DESC");
                    Collection keys = new ArrayList();
                    while (ans.next()) {
                        keys.add(new Long(ans.getLong(Consts.OBJECTS__OBJECT_ID)));
                    }
                    return keys;
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new FinderException(e.toString());
            }
        }
        throw new FinderException("key is null");
    }

    public java.util.Collection ejbFindByParentKey(java.lang.Long key, String type) throws FinderException {
        if (key != null) {
            try {
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    object_type_id = getObjectTypeID(type);
                    ans = query.executeQuery("SELECT * "
                            + " FROM " + Consts.OBJECTS__TABLENAME
                            + " WHERE "
                            + Consts.OBJECTS__PARENT_ID + "=" + key + " AND "
                            + Consts.OBJECTS__OBJECT_TYPE_ID + "=" + object_type_id
                            + " ORDER BY "+Consts.OBJECTS__TIME+" DESC");
                    Collection keys = new ArrayList();
                    while (ans.next()) {
                        keys.add(new Long(ans.getLong(Consts.OBJECTS__OBJECT_ID)));
                    }
                    return keys;
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new FinderException(e.toString());
            }
        }
        throw new FinderException("key is null");
    }

    public java.util.Collection ejbFindMByFieldSet(Arch doc, String object_type_name) throws FinderException {
        if (Consts.DEBUG_MODE) System.out.println("RDB.findMbyFieldSet hasim");
        if ((doc != null) && (object_type_name != null)) {
            try {
                getObjectTypeID(object_type_name);
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();                    
                    Arch[] elements = doc.getChilds();
                    String archquerry = null;
                    for (int i = 0; i < elements.length; i++) {
                        String val = elements[i].getValue();
                        Long attr_id = getAttributeID(elements[i].getName());
                        if (attr_id!=null){
                            //первый отсев
                            if (archquerry == null) {
                                archquerry = "SELECT DISTINCT " + Consts.PARAMS__OBJECT_ID + " FROM " + Consts.PARAMS_TABLENAME + " WHERE "
                                        + Consts.PARAMS__ATTRIBUTE_ID + "=" + attr_id + " AND "
                                        + Consts.PARAMS__VALUE + "='" + val + "'";
                            } else {
                                archquerry = "SELECT " + Consts.PARAMS__OBJECT_ID + " FROM " + Consts.PARAMS_TABLENAME + " WHERE "
                                        + Consts.PARAMS__ATTRIBUTE_ID + "=" + attr_id + " AND "
                                        + Consts.PARAMS__VALUE + "='" + val + "' AND "
                                        + Consts.PARAMS__OBJECT_ID + " IN (" + archquerry + ")";
                            }
                        }
                    }
                    if (Consts.DEBUG_MODE) System.out.print(archquerry);
                    if (archquerry==null) return null;
                    archquerry = "SELECT "+Consts.OBJECTS__OBJECT_ID
                            + " FROM "+Consts.OBJECTS__TABLENAME
                            + " WHERE " + Consts.OBJECTS__OBJECT_ID+" IN ("+archquerry+") "
                            + " ORDER BY "+Consts.OBJECTS__TIME + " DESC";
                    ans = query.executeQuery(archquerry);
                    Collection keys = new ArrayList();
                    while (ans.next()) {
                        keys.add(new Long(ans.getLong(Consts.OBJECTS__OBJECT_ID)));
                    }
                    if (Consts.DEBUG_MODE) System.out.println("        find: "+keys.size());
                    for (int i=0;i<keys.size();i++){
                        if (Consts.DEBUG_MODE) System.out.println(keys.toArray()[i]+"   ");
                    }
                    return keys;
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new FinderException(e.toString());
            }
        }
        throw new FinderException("key is null");
    }

    public java.lang.Long ejbFindByFieldSet(Arch doc, String object_type_name) throws FinderException {
        if ((doc != null) && (object_type_name != null)) {
            try {
                getObjectTypeID(object_type_name);
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    Arch[] elements = doc.getChilds();
                    String archquerry = null;
                    for (int i = 0; i < elements.length; i++) {
                        String val = elements[i].getValue();
                        Long attr_id = getAttributeID(elements[i].getName());
                        if (attr_id!=null){
                            //первый отсев
                            if (archquerry == null) {
                                archquerry = "SELECT DISTINCT " + Consts.PARAMS__OBJECT_ID + " FROM " + Consts.PARAMS_TABLENAME + " WHERE "
                                        + Consts.PARAMS__ATTRIBUTE_ID + "=" + attr_id + " AND "
                                        + Consts.PARAMS__VALUE + "='" + val + "'";
                            } else {
                                archquerry = "SELECT " + Consts.PARAMS__OBJECT_ID + " FROM " + Consts.PARAMS_TABLENAME + " WHERE "
                                        + Consts.PARAMS__ATTRIBUTE_ID + "=" + attr_id + " AND "
                                        + Consts.PARAMS__VALUE + "='" + val + "' AND "
                                        + Consts.PARAMS__OBJECT_ID + " IN (" + archquerry + ")";
                            }
                        }
                    }
                    if (Consts.DEBUG_MODE) System.out.print(archquerry);
                    if (archquerry==null) return null;
                    ans = query.executeQuery(archquerry);
                    if (ans.next()) {
                        return new Long(ans.getLong(Consts.PARAMS__OBJECT_ID));
                    } else {
                        throw new FinderException("not object for " + doc);
                    }
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new FinderException(e.toString());
            }
        }
        throw new FinderException("key is null");
    }

    //public java.lang.Long ejbCreateObj(unc.pds.util.Arch doc) throws CreateException {
    public void ejbPostCreate(unc.pds.util.Arch doc, Long nsessionKey) {
    }

    private void secCheckCreate(Arch doc) throws PDSSecurityException {
        /*
        IPDSSecurity securityModele = null;
        try {
            securityModele = SecurityST.getSecurity(sessionKey);
        } catch (Exception ex) {
            throw new CannotInitSecurityException("RDB.create " + ex.getLocalizedMessage());
        }
        Long parentID = null;
        if (doc.getChild(Consts.ARCH_F_PARENT) != null) {
            parentID = new Long(Long.parseLong(doc.getChild(Consts.ARCH_F_PARENT).getValue()));
        }
        String entity = doc.getChild(Consts.ARCH_F_TYPE).getValue();
        try {
            if (!securityModele.getCrPermission(parentID, entity)) {
                throw new NotEnoughRightException();
            }
        } catch (RemoteException ex) {
            throw new CannotInitSecurityException("RDB.create " + ex.getLocalizedMessage());
        }*/
    }

    public java.lang.Long ejbCreate(unc.pds.util.Arch doc, Long nsessionKey) throws CreateException, PDSSecurityException {
        if (doc == null) {
            throw new CreateException("RDB: Create: Empty doc");
        }
        sessionKey = nsessionKey;
        secCheckCreate(doc);
        String type = doc.getChild(Consts.ARCH_F_TYPE).getValue();
        //if (Consts.DEBUG_MODE) System.out.println("EC: " + type);
        object_type_id = getObjectTypeID(type);
        object_id = KeyGen.getInstance().getKey();
        if (Consts.DEBUG_MODE) System.out.println("RDB.create: type is: " + type + " key: " + object_id + " obj type id: " + object_type_id);
        //добавляем запись в таблицу объектов
        try {
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                String names = Consts.OBJECTS__OBJECT_ID + "," + Consts.OBJECTS__OBJECT_TYPE_ID;
                String values = ") VALUES ("
                        + object_id + "," + object_type_id;
                if (doc.getChild(Consts.ARCH_F_NAME) != null) {
                    names += "," + Consts.OBJECTS__NAME;
                    values += ",'" + doc.getChild(Consts.ARCH_F_NAME).getValue().replace("'", "''") + "'";
                }
                if (doc.getChild(Consts.ARCH_F_PARENT) != null) {
                    names += "," + Consts.OBJECTS__PARENT_ID;
                    values += "," + doc.getChild(Consts.ARCH_F_PARENT).getValue();
                }
                query = conn.createStatement();
                String endquerry = "INSERT INTO OBJECTS ("
                        + names
                        + values + ")";
                if (Consts.DEBUG_MODE) System.out.println("        " + endquerry);
                ans = query.executeQuery(endquerry);
                if (Consts.DEBUG_MODE) System.out.println("        object crseated");
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR: RDB.create: " + ex.getLocalizedMessage());
            throw new CreateException("ERROR: RDB.create: " + ex.getLocalizedMessage());
        }
        //заполняем поля в PARAMS
        try {

            for (int i = 0; i < doc.getChilds().length; i++) {
                Arch child = doc.getChilds()[i];
                if ((child.getName().compareTo(Consts.ARCH_F_NAME) != 0)
                        && (child.getName().compareTo(Consts.ARCH_F_PARENT) != 0)
                        && (child.getName().compareTo(Consts.ARCH_F_TYPE) != 0)) {
                    addParameterOnCreate(child.getName(), child.getValue().replace("'", "''"));
                }
            }
        } catch (Exception ex) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR: RDB.create attrs: " + ex.getLocalizedMessage());
            throw new CreateException("ERROR: RDB.create attrs: " + ex.getLocalizedMessage());
        }
        if (Consts.DEBUG_MODE) System.out.println("        parameters created");
        return object_id;
    }

    private Connection getConnection() throws NamingException, SQLException {
        DataSource ds = (DataSource) (new InitialContext()).lookup("oracle/SOS");
        return ds.getConnection();
    }

    public Long getID() {
        return object_id;
    }

    public Long getParentID() {
        return parent_id;
    }

    public String getName() {
        return name;
    }

    public Date getCrDate() {
        return date;
    }

    public String getObjectTypeName() {
        if (object_type_name == null) {
            try {
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("SELECT * FROM OBJECT_TYPES "
                            + "WHERE OBJECT_TYPE_ID='" + object_type_id + "'");
                    if (ans.next()) {
                        object_type_name = ans.getString(Consts.OBJECT_TYPES__NAME);
                    } else {
                        throw new EJBException("not such emp");
                    }
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new EJBException("load: " + e.toString());
            }
        }
        return object_type_name;
    }

    private Long getObjectTypeID(String name) {
        //if (object_type_id == null)
        {
            try {
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("SELECT * FROM OBJECT_TYPES "
                            + "WHERE NAME='" + name + "'");
                    if (ans.next()) {
                        object_type_id = new Long(ans.getLong(Consts.OBJECT_TYPES__ID));
                    } else {
                        throw new EJBException("not such object_type " + name);
                    }
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception e) {
                throw new EJBException("load: " + e.toString());
            }
        }
        return object_type_id;
    }

    private Long getAttributeID(String name) throws FinderException {

        try {
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("SELECT * FROM ATTRIBUTES "
                        + "WHERE OBJECT_TYPE_ID='" + object_type_id + "' AND "
                        + "NAME='" + name + "'");
                if (ans.next()) {
                    return new Long(ans.getLong(Consts.ATTRIBUTES__ATTRIBUTE_ID));
                } else {
                    throw new FinderException("not attr_id for " + name);
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getAttr_id: " + e.toString());
        }
    }

    private void secCheckRead(String field) throws PDSSecurityException {
        /*
        IPDSSecurity securityModele = null;
        try {
            securityModele = SecurityST.getSecurity(sessionKey);
        } catch (Exception ex) {
            throw new CannotInitSecurityException("RDB.read " + ex.getLocalizedMessage());
        }
        try {
            if (!securityModele.getPermission(object_id, field, "read")) {
                throw new NotEnoughRightException();
            }
        } catch (RemoteException ex) {
            throw new CannotInitSecurityException("RDB.read " + ex.getLocalizedMessage());
        }*/
    }

    private void secCheckWrite(String field) throws PDSSecurityException {
        /*
        IPDSSecurity securityModele = null;
        try {
            securityModele = SecurityST.getSecurity(sessionKey);
        } catch (Exception ex) {
            throw new CannotInitSecurityException("RDB.write " + ex.getLocalizedMessage());
        }
        try {
            if (!securityModele.getPermission(object_id, field, "write")) {
                throw new NotEnoughRightException();
            }
        } catch (RemoteException ex) {
            throw new CannotInitSecurityException("RDB.write " + ex.getLocalizedMessage());
        }*/
    }

    private void secCheckDelete(String field) throws PDSSecurityException {
        /*
        IPDSSecurity securityModele = null;
        try {
            securityModele = SecurityST.getSecurity(sessionKey);
        } catch (Exception ex) {
            throw new CannotInitSecurityException("RDB.write " + ex.getLocalizedMessage());
        }
        try {
            if (!securityModele.getPermission(object_id, field, "delete")) {
                throw new NotEnoughRightException();
            }
        } catch (RemoteException ex) {
            throw new CannotInitSecurityException("RDB.write " + ex.getLocalizedMessage());
        }*/
    }

    public String getParameter(String name) throws PDSSecurityException {
        if (Consts.DEBUG_MODE) System.out.println("RDB.getParamenter try for " + name);
        secCheckRead(name);
        if (fields.containsKey(name)) return (String) fields.get(name);
        try {
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID='" + object_id + "' AND "
                        + "ATTRIBUTE_ID='" + attr_id + "'");
                if (ans.next()) {
                    String res = ans.getString(Consts.PARAMS__VALUE);
                    fields.put(name,res);
                    return res;
                } else {
                    return null;
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getParameter: " + e.toString());
        }
    }

    public String[] getParameters(String name) throws PDSSecurityException {
        if (Consts.DEBUG_MODE) System.out.println("RDB.getParamenters try for " + name);
        secCheckRead(name);
        try {
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                String qu = "SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID='" + object_id + "' AND "
                        + "ATTRIBUTE_ID='" + attr_id + "'";
                if (Consts.DEBUG_MODE) System.out.println(qu);
                ans = query.executeQuery(qu);
                ResultSetMetaData rsmd = ans.getMetaData();
                ArrayList params = new ArrayList();
                while (ans.next()) {
                    params.add(ans.getString(Consts.PARAMS__VALUE));
                }
                String[] answer = new String[params.size()];
                return (String[]) params.toArray(answer);
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException(e.toString());
        }
    }

    //добавляет, если тот не создан или изменяет параметр.
    public void setParameter(String name, String value) throws PDSSecurityException {
        secCheckWrite(name);
        fields.put(name, value);
        try {
            //проверяем параметр на наличие
            if (getParameter(name).compareTo(value) == 0) {
                return;
            }
            //параметр есть и отличен, значит обновить параметр
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("UPDATE PARAMS SET "
                        + Consts.PARAMS__VALUE + "='" + value.replace("'", "''") + "' "
                        + "WHERE "
                        + Consts.PARAMS__OBJECT_ID + "=" + object_id + " AND "
                        + Consts.PARAMS__ATTRIBUTE_ID + "='" + attr_id + "");
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            //не смогли получить параметр, значит надо добавить.
            try {
                Long attr_id = getAttributeID(name);
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query= null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("INSERT INTO PARAMS ("
                            + Consts.PARAMS__OBJECT_ID + ","
                            + Consts.PARAMS__ATTRIBUTE_ID + ","
                            + Consts.PARAMS__VALUE + ") VALUES ("
                            + object_id + ","
                            + attr_id + ",'"
                            + value.replace("'", "''") + "')");
                    return;
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception ex) {
            }
        }

    }

    //добавляет параметр.
    private void addParameterOnCreate(String name, String value) throws Exception {
        if (Consts.DEBUG_MODE) System.out.println("RDB.addParamenterOnCreate " + name + " " + value + " start");
        try {
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("INSERT INTO PARAMS ("
                        + Consts.PARAMS__OBJECT_ID + ","
                        + Consts.PARAMS__ATTRIBUTE_ID + ","
                        + Consts.PARAMS__VALUE + ") VALUES ("
                        + object_id + ","
                        + attr_id + ",'"
                        + value.replace("'", "''") + "')");
                if (Consts.DEBUG_MODE) System.out.println("        success");
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR: RDB: ADDPARAMETER: " + ex.getLocalizedMessage());
            throw new Exception("ERROR: RDB: ADDPARAMETER: " + ex.getLocalizedMessage());
        }

    }

    //добавляет параметр.
    public void addParameter(String name, String value) throws Exception {
        if (Consts.DEBUG_MODE) System.out.println("RDB.addParamenter " + name + " " + value + " start");
        secCheckWrite(name);
        fields.put(name, value);
        try {
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("INSERT INTO PARAMS ("
                        + Consts.PARAMS__OBJECT_ID + ","
                        + Consts.PARAMS__ATTRIBUTE_ID + ","
                        + Consts.PARAMS__VALUE + ") VALUES ("
                        + object_id + ","
                        + attr_id + ",'"
                        + value.replace("'", "''") + "')");
                if (Consts.DEBUG_MODE) System.out.println("        success");
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
            if (Consts.DEBUG_MODE) System.out.println("ERROR: RDB: ADDPARAMETER: " + ex.getLocalizedMessage());
            throw new Exception("ERROR: RDB: ADDPARAMETER: " + ex.getLocalizedMessage());
        }

    }

    public void dropParameter(String name, String value) throws PDSSecurityException {
        secCheckDelete(name);
        fields.remove(name);
        try {
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans  = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("DELETE FROM PARAMS WHERE "
                        + Consts.PARAMS__VALUE + "='" + value.replace("'", "''") + "' AND "
                        + Consts.PARAMS__OBJECT_ID + "=" + object_id + " AND "
                        + Consts.PARAMS__ATTRIBUTE_ID + "=" + attr_id + "");
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
        }

    }

    public void dropParameterList() {
        fields.clear();
        try {
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("DELETE FROM PARAMS WHERE "
                        + Consts.PARAMS__OBJECT_ID + "=" + object_id);
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
        }

    }

    public void dropContentList() {
        try {
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("DELETE FROM CONTENT WHERE "
                        + Consts.CONTENT__OBJECT_ID + "=" + object_id);
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
        }

    }

    public String getContent(String name) throws EJBException, RemoteException, PDSSecurityException {
        secCheckRead(name);
        if (contents.containsKey(name)) return (String) contents.get(name);
        try {
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                String qu = "SELECT * FROM CONTENT "
                        + "WHERE OBJECT_ID='" + object_id + "' AND "
                        + "ATTRIBUTE_ID='" + attr_id + "'";
                if (Consts.DEBUG_MODE) System.out.println(qu);
                ans = query.executeQuery(qu);
                if (ans.next()) {
                    if (Consts.DEBUG_MODE) System.out.println(qu);
                    String res = ans.getClob(Consts.CONTENT__VALUE).getSubString(1, (int) ans.getClob(Consts.CONTENT__VALUE).length());
                    if (Consts.DEBUG_MODE) System.out.println("        Content is: " + res );
                    contents.put(name, res);
                    return res;
                } else {
                    throw new FinderException("not content for " + name
                            + " attr_id: " + attr_id);
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getParameter: " + e.toString());
        }
    }

    public void setContent(String name, String content) throws EJBException, RemoteException, PDSSecurityException {
        secCheckWrite(name);
        contents.put(name, content);
        try {
            //проверяем параметр на наличие
            if (getParameter(name).compareTo(content) == 0) {
                return;
            }
            //параметр есть и отличен, значит обновить параметр
            Long attr_id = getAttributeID(name);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("UPDATE CONTENT SET "
                        + Consts.CONTENT__VALUE + "='" + content.replace("'", "''") + "' "
                        + "WHERE "
                        + Consts.CONTENT__OBJECT_ID + "=" + object_id + " AND "
                        + Consts.CONTENT__ATTRIBUTE_ID + "='" + attr_id + "");
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            //не смогли получить параметр, значит надо добавить.
            try {
                Long attr_id = getAttributeID(name);
                Connection conn = getConnection();
                ResultSet ans = null;
                Statement query = null;
                try {
                    query = conn.createStatement();
                    ans = query.executeQuery("INSERT INTO CONTENT ("
                            + Consts.CONTENT__OBJECT_ID + ","
                            + Consts.CONTENT__ATTRIBUTE_ID + ","
                            + Consts.CONTENT__VALUE + ") VALUES ("
                            + object_id + ","
                            + attr_id + ",'"
                            + content.replace("'", "''") + "')");
                    return;
                } finally {
                    if (ans!=null) ans.close();
                    if (query!=null) query.close();
                    conn.close();
                }
            } catch (Exception ex) {
            }
        }
    }

    public void dropMe() throws RemoteException {
        try {
            //убиваем детей
            RootDataBeanRemoteHome rdbrh =
                    (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
            Collection bean = rdbrh.findByParentKey(this.object_id);
            for (int i = 0; i < bean.size(); i++) {
                ((RootDataBeanRemote) bean.toArray()[i]).dropMe();
            }
            //дропаем параметры
            dropParameterList();
            //дропаем контент, если он есть
            dropContentList();
            //убиваем себя
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("DELETE FROM OBJECTS WHERE "
                        + Consts.PARAMS__OBJECT_ID + "=" + object_id);
                return;
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception ex) {
            throw new RemoteException("RDB: dropMe: " + ex.getLocalizedMessage());
        }
    }

    public void eraseMe() throws RemoteException {
        try {
            //дропаем параметры
            dropParameterList();
            //дропаем контент, если он есть
            dropContentList();
        } catch (Exception ex) {
            throw new RemoteException("RDB: dropMe: " + ex.getLocalizedMessage());
        }
    }

    public boolean isAuthor(Long auKey){
        Long compare = new Long(Long.parseLong(getAuthor()));
        return (compare.compareTo(auKey)==0);
    }

    private String getAuthor() {
        if (Consts.DEBUG_MODE) System.out.println("RDB.getAuthor");
        if (author!=null) return author;
        try {
            //Long attr_id = getAttributeID(Consts.ATTR__AUTHOR);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                //ans = query.executeQuery("SELECT * FROM PARAMS "
                //        + "WHERE OBJECT_ID='" + object_id + "' AND "
                //        + "ATTRIBUTE_ID='" + attr_id + "'");
                ans = query.executeQuery("SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID='" + object_id + "' AND "
                        + "ATTRIBUTE_ID=(SELECT ATTRIBUTE_ID FROM ATTRIBUTES "
                        + "WHERE OBJECT_TYPE_ID='" + object_type_id + "' AND "
                        + "NAME='" + Consts.ATTR__AUTHOR + "')");
                if (ans.next()) {
                    if (Consts.DEBUG_MODE) System.out.println("        " + ans.getString(Consts.PARAMS__VALUE));
                    author = ans.getString(Consts.PARAMS__VALUE);
                    return author;
                } else {
                    return null;
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getParameter: " + e.toString());
        }
    }

    public boolean isOwnerSomehow(Long key) throws RemoteException {
        if (Consts.DEBUG_MODE) System.out.println("RDB.isOwnerSomehow by " + key + " for " + object_id);
        if (key == object_id) {
            return true;
        }
        String authorKey = getAuthor();
        if (authorKey != null) {
            if ((new Long(Long.parseLong(authorKey))).compareTo(key) == 0) {
                return true;
            }
        }
        if ((getParentID() != null) && (getParentID().compareTo(new Long(0)) != 0)) {
            try {
                RootDataBeanRemoteHome rdbrh = (RootDataBeanRemoteHome) (new InitialContext()).lookup("ejb/RootDataBean");
                RootDataBeanRemote rdbr = rdbrh.findByPrimaryKey(getParentID());
                return rdbr.isOwnerSomehow(key);
            } catch (Exception ex) {
                throw new RemoteException("Error: RDB.isOwnerSomehow: " + ex.getLocalizedMessage());
            }
        }
        return false;
    }

    public void setSessionKey(Long nsessionKey) {
        sessionKey = nsessionKey;
    }

    private Hashtable friendlist;
    public boolean isFriend(Long key) throws RemoteException {
        if (Consts.DEBUG_MODE) System.out.println("RDB.isFriend try for " + name);
        if (friendlist.containsKey(key)) return true;
        try {
            Long attr_id = getAttributeID(Consts.ATTR__USER_FRIEND);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID=" + object_id + " AND "
                        + "ATTRIBUTE_ID=" + attr_id + " AND "
                        + Consts.PARAMS__VALUE+"='"+key.toString()+"'");
                if (ans.next()) {
                    friendlist.put(key, new Boolean(true));
                    return true;
                } else {
                    return false;
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getParameter: " + e.toString());
        }
    }

    private Hashtable enemylist;
    public boolean isEnemy(Long key) throws RemoteException {
        if (Consts.DEBUG_MODE) System.out.println("RDB.isEnemy try for " + name);
        if (enemylist.containsKey(key)) return true;
        try {
            Long attr_id = getAttributeID(Consts.ATTR__USER_BANFRIEND);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID=" + object_id + " AND "
                        + "ATTRIBUTE_ID=" + attr_id + " AND "
                        + Consts.PARAMS__VALUE+"='"+key.toString()+"'");
                if (ans.next()) {
                    enemylist.put(key, new Boolean(true));
                    return true;
                } else {
                    return false;
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getParameter: " + e.toString());
        }
    }

    private Hashtable wanfriendlist;
    public boolean isWannedFriend(Long key) throws RemoteException{
        if (Consts.DEBUG_MODE) System.out.println("RDB.isWannaFriend try for " + name);
        if (wanfriendlist.containsKey(key)) return true;
        try {
            Long attr_id = getAttributeID(Consts.ATTR__USER_WANNEDFRIEND);
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID=" + object_id + " AND "
                        + "ATTRIBUTE_ID=" + attr_id + " AND "
                        + Consts.PARAMS__VALUE+"='"+key.toString()+"'");
                if (ans.next()) {
                    wanfriendlist.put(key, new Boolean(true));
                    return true;
                } else {
                    return false;
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("getParameter: " + e.toString());
        }
    }

    public boolean hasField(String name, String value) throws RemoteException{
        try {
            Long attr_id = getAttributeID(name);
            if (attr_id==null) return false;
            Connection conn = getConnection();
            ResultSet ans = null;
            Statement query = null;
            try {
                query = conn.createStatement();
                ans = query.executeQuery("SELECT * FROM PARAMS "
                        + "WHERE OBJECT_ID=" + object_id + " AND "
                        + "ATTRIBUTE_ID=" + attr_id + " AND "
                        + Consts.PARAMS__VALUE+"='"+value.replace("'", "''")+"'");
                if (ans.next()) {
                    return true;
                } else {
                    return false;
                }
            } finally {
                if (ans!=null) ans.close();
                if (query!=null) query.close();
                conn.close();
            }
        } catch (Exception e) {
            throw new EJBException("hasField: " + e.toString());
        }
    }
}
